    /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nc.kyiv.yellow.sociallibrary.social;

import com.nc.kyiv.yellow.sociallibrary.POJO.LibUser;
import com.nc.kyiv.yellow.sociallibrary.POJO.SessionInfo;
import com.nc.kyiv.yellow.sociallibrary.dao.UserDAO;
import com.nc.kyiv.yellow.sociallibrary.helper.Sessions;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 *
 * @author My
 */
public abstract class OAuthClient extends HttpServlet {

    //main method for getting personal data for registration or authentication from social networks
    protected String getPersonalData(HttpServletRequest request, String urlBeginingForAccessToken,
            String clientId, String clientSecret, String redirectUri, String urlForPersonalData) throws IOException {
        
        StringBuilder stringUrlForAccessToken = new StringBuilder();
        stringUrlForAccessToken.append(urlBeginingForAccessToken);
        stringUrlForAccessToken.append("?client_id=");
        stringUrlForAccessToken.append(clientId);
        stringUrlForAccessToken.append("&client_secret=");
        stringUrlForAccessToken.append(clientSecret);
        stringUrlForAccessToken.append("&code=");
        stringUrlForAccessToken.append(request.getParameter("code"));
        stringUrlForAccessToken.append("&redirect_uri=");
        stringUrlForAccessToken.append(redirectUri);
        
        String urlForAccessToken = stringUrlForAccessToken.toString();
        
        String access_token = getPureAccessToken(urlForAccessToken);
        String personalData = getStringFromHTMLwithGetMethod(urlForPersonalData + access_token);
        return personalData;
    }

    //abstract method for getting access_tokeb. Must be implemented in every inherited class
    protected abstract String getPureAccessToken(String urlForAccessToken);

    //sends Get request to URL and saves response data to String
    protected final String getStringFromHTMLwithGetMethod(String stringUrl) throws IOException {
        URL url = new URL(stringUrl);
        HttpURLConnection conn;
        BufferedReader rd;
        StringBuilder result = new StringBuilder();
        String line;
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }
        return result.toString();
    }

    //simple JSON parser (creates Map from JSON)
    //converts JSON to Map
    protected final Map<String, String> parseJSON(String json) {
        json = prepareJsonString(json);
        //System.out.println(json);
        String[] lines = json.split("\r\n");
        Map<String, String> parsedMap = new HashMap<>();

        for (int i = 0; i < lines.length; i++) {
            String line = lines[i];
            String[] pair = line.split(":");

            if (pair.length == 2) {
                String key = pair[0].trim();
                String value = pair[1].trim();
                System.out.println(key + " = " + value);
                parsedMap.put(key, value);
            }
        }
        return parsedMap;
    }

    //insert line spaces after "{", "}", ",", "[", "]" symbols and removes these symbols
    private final String prepareJsonString(String stringJSON) {
        String jsonWithLineSpaces = stringJSON;
        jsonWithLineSpaces = jsonWithLineSpaces.replace("{", "\r\n");
        jsonWithLineSpaces = jsonWithLineSpaces.replace(",", "\r\n");
        jsonWithLineSpaces = jsonWithLineSpaces.replace("[", "\r\n");
        jsonWithLineSpaces = jsonWithLineSpaces.replace("}", "\r\n");
        jsonWithLineSpaces = jsonWithLineSpaces.replace("]", "\r\n");
        jsonWithLineSpaces = jsonWithLineSpaces.replace("\"", "");
        return jsonWithLineSpaces;
    }

    //sends Get request to URL and saves response data to String
    protected final String getStringFromHTMLwithPostMethod(String stringUrl, String params) throws IOException {
        URL url = new URL(stringUrl);
        HttpURLConnection conn;
        BufferedReader rd;
        StringBuilder result = new StringBuilder();
        String line;
        conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("charset", "utf-8");
        conn.setRequestProperty("Content-Length", "" + Integer.toString(params.getBytes().length));
        conn.setUseCaches(false);

        try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
            wr.writeBytes(params);
            wr.flush();
        }
        conn.disconnect();
        
        rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }
        return result.toString();
    }

    //inserting or updaring user (is used with registration or authentification via social networks)
    void save(LibUser user) {
        try {
            UserDAO dao = new UserDAO();
            dao.insertOrUpdate(user);
            System.out.println("INSERTED OR UPDATED");
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }

    //loading user data and putting them into session
    void login(LibUser user, HttpServletRequest req) {
        UserDAO dao = null;
        try {
            dao = new UserDAO();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
        Map<String, String> params = new HashMap<>();
        params.put("login", user.getLogin());
        params.put("pass", user.getPass());
        LibUser loadedUser = dao.getUserByLoginAndPass(params);

        Sessions sessionActivity = new Sessions();
        Map userInfo = new HashMap< String, String>();
        userInfo.put("userId", loadedUser.getId());
        userInfo.put("userLogin", loadedUser.getLogin());
        userInfo.put("userPass", loadedUser.getPass());
        userInfo.put("userFirstName", loadedUser.getFirstName());
        userInfo.put("userRole", loadedUser.getRole());

        SessionInfo aboutUser = new SessionInfo();
        aboutUser.setUserId(userInfo.get("userId").toString());
        aboutUser.setUserLogin(userInfo.get("userLogin").toString());
        aboutUser.setUserPass(userInfo.get("userPass").toString());
        aboutUser.setUserFirstName(userInfo.get("userFirstName").toString());
        aboutUser.setUserRole(userInfo.get("userRole").toString());
        HttpSession Session = sessionActivity.createNewSession(aboutUser, req.getSession());
    }
    
    protected Date getUnifiedBirthDate(String rawBirthdate, String date_format){
        Date date = null;
        try {
            DateFormat format = new SimpleDateFormat(date_format);
            date = (Date) format.parseObject(rawBirthdate);
            //System.out.println(format.format(date));
        } catch (ParseException ex) {
            System.out.println("Can't parse date. Error:" + ex.getMessage());
        }
        return date;
    }
    
    
    
    
    
    //dont delete! work is in progress!
//     protected final Map<String, String> parseJSON1(String json) {
//        json = prepareJsonString1(json);
//        //System.out.println(json);
//        String[] lines = json.split("\r\n");
//        Map<String, String> parsedMap = new HashMap<>();
//        Stack<String> stack = new Stack<>();
//
//        for (int i = 0; i < lines.length; i++) {
//            String line = lines[i];
//            String[] pair = line.split(":");
//
//            if (pair.length == 2) {
//                 //System.out.println(pair[0] + "=" + pair[1]);
//
//                String key = clearStirng(pair[0]);
//                String value = clearStirng(pair[1]);
//                if (value.equals("{")) {
//                    stack.push(key);
//                } else {
//                    if (stack.size() > 0) {
//                        key = join(stack, "_");
//                    }
//                    if (parsedMap.containsKey(key)) {
//                        String newValue = parsedMap.get(key) + "&" + value;
//                        parsedMap.put(key, newValue);
//                    } else {
//                        System.out.println(key + " = " + value);
//                        parsedMap.put(key, value);
//                    }
//                }
//            } else if (line.indexOf("}") != -1 && stack.size() > 0) {
//                stack.pop();
//            }
//        }
//        return parsedMap;
//    }

     
     

//    private final String prepareJsonString1(String stringJSON) {
//        String jsonWithLineSpaces = stringJSON;
//        jsonWithLineSpaces = jsonWithLineSpaces.replace("{", "{\r\n");
//        jsonWithLineSpaces = jsonWithLineSpaces.replace(",", ",\r\n");
//        jsonWithLineSpaces = jsonWithLineSpaces.replace("[", "[\r\n");
//        jsonWithLineSpaces = jsonWithLineSpaces.replace("}", "\r\n}");
//        jsonWithLineSpaces = jsonWithLineSpaces.replace("]", "]\r\n");
//        jsonWithLineSpaces = jsonWithLineSpaces.replace("\"", "\"");
//        System.out.println(jsonWithLineSpaces);
//        return jsonWithLineSpaces;
//    }
//
//    private final String clearStirng(String str) {
//        str = str.trim();
//        int index0 = str.indexOf("\"");
//        int index1 = str.lastIndexOf("\"");
//        if (index0 != -1 && index1 > index0) {
//            str = str.substring(index0, index1);
//        } 
//        if (str.endsWith(",")) {
//            str = str.substring(0, str.length() - 1);
//        }
//        return str;
//    }
//
//    String join(Collection<?> s, String delimiter) {
//        StringBuilder builder = new StringBuilder();
//        Iterator<?> iter = s.iterator();
//        while (iter.hasNext()) {
//            builder.append(iter.next());
//            if (!iter.hasNext()) {
//                break;
//            }
//            builder.append(delimiter);
//        }
//        return builder.toString();
//    }
}
